﻿<?php
//返回失败的json
function return_error($msg)
{
  echo(json_encode([
    'code'=>404,
    'data'=>'',
    'msg'=>$msg
  ]));
  exit;
}

//返回成功
function return_ok($data)
{
  echo(json_encode([
    'code'=>200,
    'data'=>$data,
    'msg'=>'请求成功'
  ]));
  exit;
}

function randomkeys($param){
  $str="0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
  $key = "";
  for($i=0;$i<$param;$i++)
   {
       $key .= $str{mt_rand(0,32)};    //生成php随机数
   }
   return $key;
 }

 function post_data(){
   $receipt = $_REQUEST;
   if($receipt==null){
   $receipt = file_get_contents("php://input");
   if($receipt == null){
   $receipt = $GLOBALS['HTTP_RAW_POST_DATA'];
   }
   }
   return $receipt;
 }

 function xml2array($xml){
   //将XML转为array
   $array_data = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
    return $array_data;
 }

class pay{
  //支付
  function Pay($total_fee,$openid,$order_id){
      if(empty($total_fee)){
        return_error('金额有误');
      }
      if(empty($openid)){
        return_error('登录失效，请重新登录(openid参数有误)');
      }
      if(empty($order_id)){
        return_error('自定义订单有误');
      }
      $appid =  C('CFG_WEIXIN_APPID');
      $body = 'baituo';
      $mch_id = C('CFG_WEIXIN_SHANGHUHAO');
      $KEY = C('CFG_WEIXIN_SHANGHUMIYAO');
      $nonce_str =    randomkeys(32);//随机字符串
      $notify_url =   'http://guoqing.jsbestop.com/index.php/Api/Login/pay_notify';  //支付完成回调地址url
      $out_trade_no = $order_id;//商户订单号
      $spbill_create_ip = $_SERVER['SERVER_ADDR']?$_SERVER['SERVER_ADDR']:'180.76.252.192';
      $trade_type = 'JSAPI';//交易类型 默认JSAPI

      $post['appid'] = $appid;
      $post['body'] = $body;
      $post['mch_id'] = $mch_id;
      $post['nonce_str'] = $nonce_str;
      $post['notify_url'] = $notify_url;
      $post['openid'] = $openid;
      $post['out_trade_no'] = $out_trade_no;
      $post['spbill_create_ip'] = $_SERVER['SERVER_ADDR']?$_SERVER['SERVER_ADDR']:'180.76.252.192';
      $post['total_fee'] = intval($total_fee);
      $post['trade_type'] = $trade_type;
      $sign = $this->MakeSign($post,$KEY);

      $post_xml = '<xml>
             <appid>'.$appid.'</appid>
             <body>'.$body.'</body>
             <mch_id>'.$mch_id.'</mch_id>
             <nonce_str>'.$nonce_str.'</nonce_str>
             <notify_url>'.$notify_url.'</notify_url>
             <openid>'.$openid.'</openid>
             <out_trade_no>'.$out_trade_no.'</out_trade_no>
             <spbill_create_ip>'.$spbill_create_ip.'</spbill_create_ip>
             <total_fee>'.$total_fee.'</total_fee>
             <trade_type>'.$trade_type.'</trade_type>
             <sign>'.$sign.'</sign>
          </xml> ';

      $url = "https://api.mch.weixin.qq.com/pay/unifiedorder";
      $xml = $this->http_request($url,$post_xml);     //POST方式请求http
      $array = xml2array($xml);               //将【统一下单】api返回xml数据转换成数组，全要大写
      if($array['return_code'] == 'SUCCESS' && $array['return_msg'] == 'OK'){
          $time = time();
          $tmp=[];                            //临时数组用于签名
          $tmp['appId'] = $appid;
          $tmp['nonceStr'] = $nonce_str;
          $tmp['package'] = 'prepay_id='.$array['prepay_id'];
          $tmp['signType'] = 'MD5';
          $tmp['timeStamp'] = "$time";

          $data['state'] = 1;
          $data['timeStamp'] = "$time";
          $data['nonceStr'] = $nonce_str;
          $data['signType'] = 'MD5';
          $data['package'] = 'prepay_id='.$array['prepay_id'];
          $data['paySign'] = $this->MakeSign($tmp,$KEY);
          $data['out_trade_no'] = $out_trade_no;
          return_ok($data);
      }else{
          $data['state'] = 0;
          $data['text'] = "错误";
          $data['RETURN_CODE'] = $array['return_code'];
          $data['RETURN_MSG'] = $array['return_msg'];
          return_ok($data);
      }
  }

  //支付后的回调
  /* 微信支付完成，回调地址url方法  pay_notify() */
   public function pay_notify(){
       $post = post_data();    //接受POST数据XML个数
       $post_data = xml2array($post);   //微信支付成功，返回回调地址url的数据：XML转数组Array
       $postSign = $post_data['sign'];
       unset($post_data['sign']);

       ksort($post_data);// 对数据进行排序
       $str = $this->ToUrlParams($post_data);//对数组数据拼接成key=value字符串
       $key = C('CFG_WEIXIN_SHANGHUMIYAO');
       $sign = strtoupper(md5($str.'&key='.$key));   //再次生成签名，与$postSign比较

       $where['orderbn'] = $post_data['out_trade_no'];
       $order = M('xcxproductrecord')->where($where)->find();
       $userId = $order['member_id'];
       $productId = $order['xcxproduct_id'];
       if($sign==$postSign&&$order&&$post_data['return_code']=='SUCCESS'){
         if($order['status']=='2'){
             $this->return_success();
         }else{
             $updata['status'] = '2';
             //更新订单信息
             M('xcxproductrecord')->where($where)->save($updata);
             //获取商品信息
             $product = M('xcxproduct')->where(['id'=>$productId])->find();
             //添加百拓币返回记录
             M('xcxiconrecord')->add([
               'member_id'=>$order['member_id'],
               'type'=>"income",
               'num'=>$order['reicon'],
               'time'=>time(),
               'tip'=>'购买产品'.$product['title']
             ]);
             //给用户账户添加百拓币
             M('member')->execute("update bestop_member set icon = icon + '{$order['reicon']}' where id = '$userId'");
             $this->return_success();
         }
       }else{
           echo '微信支付失败';
       }
   }


  /**
   * 生成签名, $KEY就是支付key
   * @return 签名
   */
  private function MakeSign( $params,$KEY){
      if(isset($params['sing']))
      unset($params['sing']);
      ksort($params);
      $string = $this->ToUrlParams($params);
      $string = $string . "&key=".$KEY;
      $string = md5($string);
      $result = strtoupper($string);
      return $result;
  }
  /**
   * 将参数拼接为url: key=value&key=value
   * @param $params
   * @return string
   */
  private function ToUrlParams( $params ){
      $string = '';
      if( !empty($params) ){
          $array = array();
          foreach( $params as $key => $value ){
              $array[] = $key.'='.$value;
          }
          $string = implode("&",$array);
      }
      return $string;
  }
  /**
   * 调用接口， $data是数组参数
   * @return 签名
   */
  private function http_request($url,$data = null,$headers=array())
  {
      $curl = curl_init();
      if( count($headers) >= 1 ){
          curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
      }
      curl_setopt($curl, CURLOPT_URL, $url);

      curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
      curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);

      if (!empty($data)){
          curl_setopt($curl, CURLOPT_POST, 1);
          curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
      }
      curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
      $output = curl_exec($curl);
      curl_close($curl);
      return $output;
  }
}
